package com.zwc.angle2048;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Point;
import android.graphics.Typeface;
import android.view.KeyEvent;
import android.view.MotionEvent;

import com.zwc.angle.AngleActivity;
import com.zwc.angle.AngleFont;
import com.zwc.angle.AngleObject;
import com.zwc.angle.AngleSprite;
import com.zwc.angle.AngleSpriteLayout;
import com.zwc.angle.AngleString;
import com.zwc.angle.AngleUI;

/**
 * 时间模式 目标2048
 * 
 * @author zwc
 *
 */
public class UIOfTime extends AngleUI {
	private int width = GameUtil.WIDTH;
	private int height = GameUtil.HEIGHT;
	private List<Point> emptyPoints = new ArrayList<Point>();
	private AngleObject[][] card = new AngleObject[4][4];
	private int[][] num;
	private int[][] temp;
	private int currentTimeScore;
	private int bestTimeScore;
	private int move2;
	private float time2;
	private String strNum2;
	private boolean isStart;

	private AngleObject groupOfBg;
	private AngleObject groupOfScore;
	private AngleObject groupOfTexts;
	private AngleObject groupOfCards;
	private AngleString strNewGame;
	private AngleString strBack;
	private AngleString strMove;
	private AngleString strTime;
	private AngleString strscore;
	private AngleString strbest;

	private float startX, startY, offsetX, offsetY;

	/**
	 * 获取上次存储的信息
	 */
	private void getData() {
		isStart = false;
		strNum2 = (String) GameDB.getParam(mActivity, "strNum2",
				"0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0");
		num = GameUtil.tonum(strNum2);
		temp = GameUtil.tonum(strNum2);
		currentTimeScore = (int) GameDB.getParam(mActivity, "currentTimeScore",
				0);
		bestTimeScore = Integer.parseInt(GameUtil.toStrArr((String) GameDB
				.getParam(mActivity, "TimeScore1", "1000_100_123"))[0]);
		move2 = (int) GameDB.getParam(mActivity, "move2", 0);
		time2 = (float) GameDB.getParam(mActivity, "time2", 0.0f);
	}

	/**
	 * 初始化
	 */
	@Override
	public void onActivate() {
//		System.out.println("初始化");
		getData();
		startGame();
		super.onActivate();
	}

	/**
	 * 布局设置
	 * 
	 * @param activity
	 */
	public UIOfTime(AngleActivity activity) {
		super(activity);

		groupOfCards = new AngleObject();
		groupOfBg = new AngleObject();
		groupOfScore = new AngleObject();
		groupOfTexts = new AngleObject();
		addObject(groupOfBg);
		addObject(groupOfCards);
		addObject(groupOfScore);
		addObject(groupOfTexts);

		AngleFont font_HoneyLight = new AngleFont(mActivity.mGLSurfaceView, 50,
				Typeface.createFromAsset(mActivity.getAssets(),
						"HoneyLight.ttf"), 222, 0, 0, 30, 200, 255, 255);
		AngleFont font_bazaronitet = new AngleFont(mActivity.mGLSurfaceView,
				50, Typeface.createFromAsset(mActivity.getAssets(),
						"bazaronite.ttf"), 222, 0, 0, 0, 0, 0, 255);
		AngleFont font_Almost_Cartoon = new AngleFont(mActivity.mGLSurfaceView,
				30, Typeface.createFromAsset(mActivity.getAssets(),
						"Almost_Cartoon.ttf"), 222, 0, 0, 0, 0, 0, 255);

		groupOfBg.addObject(new AngleSprite(width / 2, height / 2,
				new AngleSpriteLayout(mActivity.mGLSurfaceView, width, height,
						com.zwc.angle2048.R.drawable.bg)));
		groupOfBg.addObject(new AngleSprite(width / 4, 90,
				new AngleSpriteLayout(mActivity.mGLSurfaceView,
						com.zwc.angle2048.R.drawable.score)));
		groupOfBg.addObject(new AngleSprite(width * 3 / 4, 90,
				new AngleSpriteLayout(mActivity.mGLSurfaceView,
						com.zwc.angle2048.R.drawable.best)));

		strNewGame = (AngleString) groupOfTexts.addObject(new AngleString(
				font_HoneyLight, "NEW", width / 4, height * 8 / 9,
				AngleString.aCenter));
		strBack = (AngleString) groupOfTexts.addObject(new AngleString(
				font_HoneyLight, "BACK", width * 3 / 4, height * 8 / 9,
				AngleString.aCenter));
		groupOfTexts.addObject(new AngleString(font_Almost_Cartoon, "move:",
				40, height * 4 / 5 + 10, AngleString.aCenter));
		strMove = (AngleString) groupOfScore.addObject(new AngleString(
				font_Almost_Cartoon, "", 80, height * 4 / 5 + 10,
				AngleString.aCenter));
		groupOfTexts.addObject(new AngleString(font_Almost_Cartoon, "time:",
				width - 100, height * 4 / 5 + 10, AngleString.aCenter));
		strTime = (AngleString) groupOfScore.addObject(new AngleString(
				font_Almost_Cartoon, "0", width - 40, height * 4 / 5 + 10,
				AngleString.aCenter));
		strscore = (AngleString) groupOfScore.addObject(new AngleString(
				font_bazaronitet, "", width / 4, height / 6,
				AngleString.aCenter));
		strbest = (AngleString) groupOfScore.addObject(new AngleString(
				font_bazaronitet, "", width * 3 / 4, height / 6,
				AngleString.aCenter));
	}

	/**
	 * 开始游戏
	 */
	private void startGame() {
		strscore.set("" + currentTimeScore);
		strbest.set("" + bestTimeScore);
		strMove.set("" + move2);
		strTime.set(GameUtil.secToTime((int) time2));
		for (int x = 0; x < 4; x++) {
			for (int y = 0; y < 4; y++) {
				addCard(x, y, num[x][y]);
			}
		}
		if (strNum2.equals("0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0")) {
			addRandomNum();
			addRandomNum();
		}
	}

	/**
	 * 重新开始游戏
	 */
	private void newGame() {
		saveGameOverScore(currentTimeScore, move2, time2);
		isStart = false;
		currentTimeScore = 0;
		move2 = 0;
		time2 = 0.0f;
		bestTimeScore = Integer.parseInt(GameUtil.toStrArr((String) GameDB
				.getParam(mActivity, "TimeScore1", "1000_100_123"))[0]);
		strscore.set("" + currentTimeScore);
		strbest.set("" + bestTimeScore);
		strMove.set("" + move2);
		strTime.set(GameUtil.secToTime((int) time2));

		temp = GameUtil.tonum("0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0");
		num = GameUtil.tonum("0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0");
		for (int x = 0; x < 4; x++) {
			for (int y = 0; y < 4; y++) {
				addCard(x, y, num[x][y]);
			}
		}
		addRandomNum();
		addRandomNum();
	}

	/**
	 * 添加一张卡片
	 * 
	 * @param x
	 * @param y
	 * @param num
	 */
	private void addCard(int x, int y, int num) {
		Card c = new Card();
		card[x][y] = c.addCard(mActivity.mGLSurfaceView, x, y, num);
		groupOfCards.addObject(card[x][y]);
	}

	/**
	 * 随机添加卡片
	 */
	private void addRandomNum() {
		Card c = new Card();
		emptyPoints.clear();
		for (int x = 0; x < 4; x++) {
			for (int y = 0; y < 4; y++) {
				if (temp[x][y] == 0) {
					emptyPoints.add(new Point(x, y));
				}
			}
		}
		if (emptyPoints.size() > 0) {
			Point p = emptyPoints.remove((int) (Math.random() * (emptyPoints
					.size())));
			int addRandom = Math.random() > 0.1 ? 2 : 4;
			temp[p.x][p.y] = addRandom;
			num[p.x][p.y] = addRandom;
			removeObject(card[p.x][p.y]);
			card[p.x][p.y] = c.addRandomCard(mActivity.mGLSurfaceView, p.x,
					p.y, addRandom);
			groupOfCards.addObject(card[p.x][p.y]);
		}
	}

	/**
	 * 显示卡片
	 */
	private void checkCard() {
		for (int x = 0; x < 4; x++) {
			for (int y = 0; y < 4; y++) {
				if (num[x][y] != temp[x][y]) {
					groupOfCards.removeObject(card[x][y]);
					num[x][y] = temp[x][y];
					addCard(x, y, num[x][y]);
				}
			}
		}
	}

	/**
	 * 触摸事件
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			isStart = true;
			startX = event.getX();
			startY = event.getY();
			if (strNewGame.test(startX, startY)) {
				groupOfCards.removeAll();
				newGame();
			} else if (strBack.test(startX, startY)) {
				// isStart = false;
				// GameDB.setParam(mActivity, "time2", time2);
				save();
				startX = 0;
				startY = 0;
				((MainActivity) mActivity)
						.setUI(((MainActivity) mActivity).mTheMenu);
			}

			break;
		case MotionEvent.ACTION_UP:
			offsetX = event.getX() - startX;
			offsetY = event.getY() - startY;
			if ((startX + startY) > 0) {
				if (Math.abs(offsetX) > Math.abs(offsetY)) {
					if (offsetX < -20) {
						moveLeft();
						// System.out.println("left");
					} else if (offsetX > 20) {
						moveRight();
						// System.out.println("right");
					}
				} else {
					if (offsetY < -20) {
						moveUp();
						// System.out.println("up");
					} else if (offsetY > 20) {
						moveDown();
						// System.out.println("down");
					}
				}
				break;
			}
		}
		return true;
	}

	/**
	 * 向左移动
	 */
	private void moveLeft() {
		boolean isMove = false;
		for (int x = 0; x < 4; x++) {
			for (int y = 0; y < 4; y++) {
				for (int y1 = y + 1; y1 < 4; y1++) {
					if (temp[x][y1] > 0) {
						if (temp[x][y] == 0) {
							temp[x][y] = temp[x][y1];
							temp[x][y1] = 0;
							y--;
							isMove = true;
						} else if (temp[x][y] == temp[x][y1]) {
							temp[x][y] = temp[x][y] * 2;
							temp[x][y1] = 0;
							addScore(temp[x][y]);
							isMove = true;
						}
						break;
					}
				}
			}
		}
		if (isMove) {
			showScore();
			checkCard();
			addRandomNum();
			checkEmpty();
			checkGoal();
		}
	}

	/**
	 * 向右移动
	 */
	private void moveRight() {
		boolean isMove = false;
		for (int x = 0; x < 4; x++) {
			for (int y = 3; y >= 0; y--) {
				for (int y1 = y - 1; y1 >= 0; y1--) {
					if (temp[x][y1] > 0) {
						if (temp[x][y] == 0) {
							temp[x][y] = temp[x][y1];
							temp[x][y1] = 0;
							y++;
							isMove = true;
						} else if (temp[x][y] == temp[x][y1]) {
							temp[x][y] = temp[x][y] * 2;
							temp[x][y1] = 0;
							addScore(temp[x][y]);
							isMove = true;
						}
						break;
					}
				}
			}
		}
		if (isMove) {
			showScore();
			checkCard();
			addRandomNum();
			checkEmpty();
			checkGoal();
		}
	}

	/**
	 * 向上移动
	 */
	private void moveUp() {
		boolean isMove = false;
		for (int y = 0; y < 4; y++) {
			for (int x = 0; x < 4; x++) {
				for (int x1 = x + 1; x1 < 4; x1++) {
					if (temp[x1][y] > 0) {
						if (temp[x][y] == 0) {
							temp[x][y] = temp[x1][y];
							temp[x1][y] = 0;
							x--;
							isMove = true;
						} else if (temp[x][y] == temp[x1][y]) {
							temp[x][y] = temp[x][y] * 2;
							temp[x1][y] = 0;
							addScore(temp[x][y]);
							isMove = true;
						}
						break;
					}
				}
			}
		}
		if (isMove) {
			showScore();
			checkCard();
			addRandomNum();
			checkEmpty();
			checkGoal();
		}
	}

	/**
	 * 向下移动
	 */
	private void moveDown() {
		boolean isMove = false;
		for (int y = 0; y < 4; y++) {
			for (int x = 3; x >= 0; x--) {
				for (int x1 = x - 1; x1 >= 0; x1--) {
					if (temp[x1][y] > 0) {
						if (temp[x][y] == 0) {
							temp[x][y] = temp[x1][y];
							temp[x1][y] = 0;
							x++;
							isMove = true;
						} else if (temp[x][y] == temp[x1][y]) {
							temp[x][y] = temp[x][y] * 2;
							temp[x1][y] = 0;
							addScore(temp[x][y]);
							isMove = true;
						}
						break;
					}
				}
			}
		}
		if (isMove) {
			showScore();
			checkCard();
			addRandomNum();
			checkEmpty();
			checkGoal();
		}
	}

	/**
	 * 添加分数
	 * 
	 * @param score
	 */
	private void addScore(int score) {
		currentTimeScore += score;
		strscore.set("" + currentTimeScore);
	}

	/**
	 * 显示分数
	 */
	private void showScore() {
		strMove.set("" + (++move2));
		if (currentTimeScore > bestTimeScore) {
			bestTimeScore = currentTimeScore;
			GameDB.setParam(mActivity, "bestTimeScore", bestTimeScore);
			strbest.set("" + bestTimeScore);
		}
	}

	/**
	 * 检查是否完成游戏
	 */
	private void checkGoal() {
		boolean complete = false;
		ALL: for (int x = 0; x < 4; x++) {
			for (int y = 0; y < 4; y++) {
				if (num[x][y] == 2048) {
					complete = true;
					break ALL;
				}
			}
		}
		if (complete) {
			groupOfCards.removeAll();
			new AlertDialog.Builder(mActivity)
					.setTitle(com.zwc.angle2048.R.string.win)
					.setMessage(com.zwc.angle2048.R.string.win1)
					.setPositiveButton(com.zwc.angle2048.R.string.restart,
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									newGame();
								}
							}).show();
		}
	}

	/**
	 * 检查是否结束
	 */
	private void checkEmpty() {
		boolean complete = true;
		ALL: for (int x = 0; x < 4; x++) {
			for (int y = 0; y < 4; y++) {
				if (num[x][y] == 0 || (x > 0 && num[x][y] == num[x - 1][y])
						|| (x < 3 && num[x][y] == num[x + 1][y])
						|| (y > 0 && num[x][y] == num[x][y - 1])
						|| (y < 3 && num[x][y] == num[x][y + 1])) {
					complete = false;
					break ALL;
				}
			}
		}
		if (complete) {
			groupOfCards.removeAll();
			new AlertDialog.Builder(mActivity)
					.setTitle(com.zwc.angle2048.R.string.lost)
					.setMessage(com.zwc.angle2048.R.string.gameover)
					.setPositiveButton(com.zwc.angle2048.R.string.restart,
							new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									newGame();
								}
							}).show();
		}
	}

	private void saveGameOverScore(int score, int move, float time) {
		String mode = "Time";
		String strGameOverScore = score + "_" + move + "_" + (int) time;
		String[] strHiScore = new String[6];
		GameDB.setParam(mActivity, mode + "Score" + 6, strGameOverScore);
		for (int i = 0; i < 6; i++) {
			String key = mode + "Score" + (i + 1);
			strHiScore[i] = (String) GameDB.getParam(mActivity, key,
					"1000_100_123");
		}
		strHiScore = GameUtil.isHiScore(strHiScore);
		for (int i = 0; i < 6; i++) {
			String key = mode + "Score" + (i + 1);
			GameDB.setParam(mActivity, key, strHiScore[i]);
		}
	}

	/**
	 * 保存数据
	 */
	private void save() {
		GameDB.setParam(mActivity, "currentTimeScore", currentTimeScore);
		GameDB.setParam(mActivity, "strNum2", GameUtil.tostring(num));
		GameDB.setParam(mActivity, "move2", move2);
		GameDB.setParam(mActivity, "time2", time2);
	}

	/**
	 * 手机右键跳转上一界面
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			save();
			((MainActivity) mActivity)
					.setUI(((MainActivity) mActivity).mTheMenu);
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	/**
	 * 时间循环
	 */
	@Override
	public void step(float secondsElapsed) {
		if (isStart) {
			int i = (int) time2;
			time2 += secondsElapsed;
			if ((int) time2 > i) {
				strTime.set("" + GameUtil.secToTime((int) time2));
				if (i % 8 == 7) {
					addRandomNum();
				}
			}
		}
		super.step(secondsElapsed);
	}
}
